<template>
  <div class="page-task-assignments glass">
    <div class="toolbar glass-bar">
      <div class="title">
        <span class="grad">学习任务矩阵</span>
        <span class="hint">T-5 ~ T+1 快速发布与查看</span>
      </div>
      <div class="controls">
        <el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" :shortcuts="shortcuts"/>
        <el-input v-model="keyword" placeholder="搜索学生" style="width:220px" clearable />
        <el-select v-model="statusFilter" placeholder="状态" style="width:140px">
          <el-option label="全部" value="all"/>
          <el-option label="待办(0/N)" value="warning"/>
          <el-option label="部分完成" value="primary"/>
          <el-option label="已完成(N/N)" value="success"/>
          <el-option label="无任务(-)" value="info"/>
        </el-select>
        <el-button type="primary" @click="loadData">查询</el-button>
        <el-button @click="exportCsv" plain>导出当日CSV</el-button>
      </div>
    </div>

    <div class="legend">
      <el-tag type="info">- 无任务</el-tag>
      <el-tag type="warning">0/N 待办</el-tag>
      <el-tag type="primary">部分完成</el-tag>
      <el-tag type="success">N/N 全部完成</el-tag>
    </div>

    <el-table :data="rows" border class="matrix-table" height="calc(100vh - 260px)">
      <el-table-column prop="studentName" label="学生" width="160" fixed />
      <el-table-column v-for="d in days" :key="d.key" :label="d.label">
        <template #default="{ row }">
          <el-popover placement="top" width="420" trigger="click" popper-class="matrix-pop">
            <template #reference>
              <button class="cell chip" :class="[cellType(row, d.key), filteredOut(row, d.key) ? 'muted' : '']" @click="openAssign(row.studentId, d.key)" :disabled="filteredOut(row, d.key)">
                <span class="num">{{ summary(row, d.key) }}</span>
              </button>
            </template>
            <div class="pop-body">
              <div class="pop-head">
                <span class="date">{{ d.key }}</span>
                <el-button size="small" type="primary" plain @click="openAssign(row.studentId, d.key)">快速发布</el-button>
              </div>
              <div v-if="(matrix[row.studentId]?.[d.key] || []).length === 0" class="empty">今日未发布任务</div>
              <ul v-else class="item-list">
                <li v-for="it in (matrix[row.studentId][d.key] || [])" :key="it.id" class="item">
                  <span class="tag">U{{ it.unitId }}</span>
                  <span class="meta">阈 {{ it.passScore ?? '-' }}</span>
                  <span class="meta">分 {{ it.score ?? '-' }}</span>
                  <el-tag size="small" :type="it.status===1?'success':'warning'">{{ it.status===1?'已完成':'待办' }}</el-tag>
                </li>
              </ul>
              <div class="edit-hint">
                明细编辑（调整阈值/删除子项）将在后续版本提供。
              </div>
            </div>
          </el-popover>
        </template>
      </el-table-column>
    </el-table>

    <el-drawer v-model="assignVisible" title="发布任务" size="40%">
      <el-form :model="assignForm" label-width="100px">
        <el-form-item label="日期">
          <el-date-picker v-model="assignForm.targetDate" type="date" />
        </el-form-item>
        <el-form-item label="学生ID">
          <el-input v-model.number="assignForm.studentId" disabled />
        </el-form-item>
        <el-form-item label="系列">
          <el-select v-model="sel.seriesId" filterable @change="onSeriesChange">
            <el-option v-for="s in series" :key="s.id" :label="s.nameZhCn || s.nameEnUs" :value="s.id"/>
          </el-select>
        </el-form-item>
        <el-form-item label="教材">
          <el-select v-model="sel.programId" filterable @change="onProgramChange">
            <el-option v-for="p in programs" :key="p.id" :label="p.nameZhCn || p.name" :value="p.id"/>
          </el-select>
        </el-form-item>
        <el-form-item label="单元">
          <el-select v-model="sel.unitId" filterable>
            <el-option v-for="u in units" :key="u.id" :label="u.name" :value="u.id"/>
          </el-select>
        </el-form-item>
        <el-form-item label="通关分数">
          <el-input-number v-model="assignForm.passScore" :min="0" :max="100" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :loading="assignLoading" @click="doAssign">发布</el-button>
          <el-button @click="assignVisible=false">取消</el-button>
        </el-form-item>
      </el-form>
    </el-drawer>
  </div>
  
</template>

<script lang="ts" setup>
import { onMounted, reactive, ref, computed } from 'vue'
import { dayjs } from 'element-plus'
import TaskAssignmentsAPI, { type TaskAssignForm, type TaskMatrixQuery } from '@/api/dcyx/task-assignments'
import DcyxUsersAPI, { type DcyxUsersPageQuery } from '@/api/dcyx/dcyx-users'
import SERIES_API from '@/api/dcyx/series'
import PROGRAMS_API from '@/api/dcyx/programs'
import UNITS_API from '@/api/dcyx/units'

const dateRange = ref<[Date, Date]>()
const keyword = ref('')
const statusFilter = ref<'all'|'info'|'warning'|'primary'|'success'>('all')
const students = ref<{id:number; fullname:string}[]>([])
const matrix = reactive<Record<number, Record<string, any[]>>>({})
const rows = computed(() => students.value.map(s=>({ studentId: s.id, studentName: s.fullname })))

const shortcuts = [
  {
    text: '过去5天~明天',
    value: () => {
      const now = dayjs()
      return [now.subtract(5,'day').toDate(), now.add(1,'day').toDate()] as [Date,Date]
    }
  }
]

const days = computed(()=>{
  const [s,e] = dateRange.value || [dayjs().subtract(5,'day').toDate(), dayjs().add(1,'day').toDate()]
  const arr: {key:string,label:string}[] = []
  let cur = dayjs(s)
  const end = dayjs(e)
  while(cur.isBefore(end) || cur.isSame(end,'day')){
    arr.push({ key: cur.format('YYYY-MM-DD'), label: cur.format('MM-DD') })
    cur = cur.add(1,'day')
  }
  return arr
})

function summary(row:any, dayKey:string){
  const items = (matrix[row.studentId]?.[dayKey]) || []
  const total = items.length
  const done = items.filter((i:any)=> i.status===1).length
  return total===0 ? '-' : `${done}/${total}`
}
function cellType(row:any, dayKey:string){
  const items = (matrix[row.studentId]?.[dayKey]) || []
  if(items.length===0) return 'info'
  const done = items.filter((i:any)=> i.status===1).length
  return done===0 ? 'warning' : (done===items.length ? 'success' : 'primary')
}

function filteredOut(row:any, dayKey:string){
  if(statusFilter.value==='all') return false
  return cellType(row, dayKey) !== statusFilter.value
}

async function loadStudents(){
  const params: DcyxUsersPageQuery = { pageNum:1, pageSize:100, fullname: keyword.value }
  const { data } = await DcyxUsersAPI.getPage(params) as any
  students.value = (data?.records || []).map((r:any)=>({ id:r.id, fullname:r.fullname || r.username }))
}

async function loadMatrix(){
  const [s,e] = dateRange.value || [dayjs().subtract(5,'day').toDate(), dayjs().add(1,'day').toDate()]
  const q: TaskMatrixQuery = { dateStart: dayjs(s).format('YYYY-MM-DD'), dateEnd: dayjs(e).format('YYYY-MM-DD'), pageNum:1, pageSize:100 }
  const { data } = await TaskAssignmentsAPI.getMatrix(q) as any
  Object.keys(data || {}).forEach((sid)=>{
    const num = Number(sid)
    matrix[num] = {}
    const m = data[sid] || {}
    Object.keys(m).forEach(day=>{ matrix[num][day] = m[day] })
  })
}

async function loadData(){
  await loadStudents()
  await loadMatrix()
}

async function exportCsv(){
  const dt = (dateRange.value?.[0]) ? dayjs(dateRange.value[0]).format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD')
  const blob = await TaskAssignmentsAPI.exportCsv(dt)
  const url = URL.createObjectURL(blob as any)
  const a = document.createElement('a')
  a.href = url
  a.download = `task-items-${dt}.csv`
  a.click()
  URL.revokeObjectURL(url)
}

// 发布抽屉
const assignVisible = ref(false)
const assignLoading = ref(false)
const assignForm = reactive<{studentId:number|null; targetDate:string|null; passScore:number|null}>({ studentId:null, targetDate:null, passScore:80 })
const sel = reactive<{seriesId:number|null; programId:number|null; unitId:number|null}>({ seriesId:null, programId:null, unitId:null })
const series = ref<any[]>([])
const programs = ref<any[]>([])
const units = ref<any[]>([])

function openAssign(studentId:number, dayKey:string){
  assignForm.studentId = studentId
  assignForm.targetDate = dayKey
  assignVisible.value = true
  bootstrapOptions()
}

async function bootstrapOptions(){
  const { data } = await SERIES_API.getSemesterList({ pageNum:1, pageSize:999 }) as any
  // 复用系列列表接口：这里假设你已有系列数据加载逻辑，如有专用接口可替换
  // 这里简化：按 programs.ts/units.ts 提供的 API 逐级加载
  const sres = await import('@/api/dcyx/series')
  const pres = await import('@/api/dcyx/programs')
  series.value = (await sres.default.getSeriesBySemesterId({ pageNum:1, pageSize:999, parentId: 0, seriesId: '', semesterId: '' }) as any).data?.records || []
}

async function onSeriesChange(){
  programs.value = []
  units.value = []
  if(!sel.seriesId) return
  const { data } = await PROGRAMS_API.getProgramsBySeriesId({ pageNum:1, pageSize:999, seriesId: String(sel.seriesId) }) as any
  programs.value = data?.records || []
}

async function onProgramChange(){
  units.value = []
  if(!sel.seriesId || !sel.programId) return
  const { data } = await PROGRAMS_API.getUnitsInfoByProgram(0, String(sel.seriesId), String(sel.programId)) as any
  // 兜底：若返回格式不同，可替换为 units.ts 的分页接口
  units.value = (data?.units || data?.records || []).map((u:any)=>({ id: u.id || u.unitId, name: u.name || u.nameZhCn || `U${u.unitId}` }))
}

async function doAssign(){
  if(!assignForm.studentId || !assignForm.targetDate || !sel.seriesId || !sel.programId || !sel.unitId){
    ElMessage.warning('请完整选择系列/教材/单元与日期')
    return
  }
  assignLoading.value = true
  try{
    const payload: TaskAssignForm = {
      studentId: assignForm.studentId!,
      targetDate: assignForm.targetDate!,
      items: [{ seriesId: sel.seriesId!, programId: sel.programId!, unitId: sel.unitId!, passScore: assignForm.passScore || 80 }]
    }
    await TaskAssignmentsAPI.assign(payload)
    ElMessage.success('发布成功')
    assignVisible.value = false
    await loadMatrix()
  }finally{
    assignLoading.value = false
  }
}

onMounted(async ()=>{
  // 默认范围 T-5~T+1
  dateRange.value = [dayjs().subtract(5,'day').toDate(), dayjs().add(1,'day').toDate()]
  await loadData()
})
</script>

<style scoped>
.page-task-assignments{ padding:16px; min-height:100vh; background: linear-gradient(120deg,#f5f7ff 0%,#f9fbff 60%,#f3f7ff 100%); }
.glass{ backdrop-filter: blur(8px); }
.glass-bar{ background: rgba(255,255,255,.6); border-radius:12px; padding:12px 16px; display:flex; align-items:center; justify-content:space-between; box-shadow: 0 10px 30px rgba(40,80,140,.08); margin-bottom:12px; }
.title{ display:flex; align-items:baseline; gap:10px }
.grad{ font-weight:700; font-size:18px; background:linear-gradient(90deg,#4e74ff,#8a8dff); -webkit-background-clip:text; background-clip:text; color:transparent }
.hint{ color:#889; font-size:12px }
.controls{ display:flex; gap:8px; align-items:center }
.legend{ display:flex; gap:8px; margin:8px 0 12px 0 }
.matrix-table :deep(.el-table__cell){ background: rgba(255,255,255,.75); }

.cell{ border:none; border-radius:10px; padding:6px 10px; cursor:pointer; font-weight:600; transition: transform .08s ease; }
.cell:hover{ transform: translateY(-1px); }
.chip.info{ background: #eef2ff; color:#5b6b8a }
.chip.warning{ background: #fff4e5; color:#9a6b21 }
.chip.primary{ background: #ecf2ff; color:#3559d8 }
.chip.success{ background: #eaf7ef; color:#2e7d32 }
.chip.muted{ opacity:.35; cursor:not-allowed }
.num{ letter-spacing:.5px }

.matrix-pop{ backdrop-filter: blur(8px); }
.pop-body{ display:flex; flex-direction:column; gap:10px }
.pop-head{ display:flex; justify-content:space-between; align-items:center }
.pop-head .date{ font-weight:600; color:#334 }
.empty{ color:#99a; font-size:13px }
.item-list{ list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:6px }
.item{ display:flex; align-items:center; gap:10px; font-size:12px }
.item .tag{ background:#eef2ff; color:#4a57c9; border-radius:6px; padding:2px 6px; font-weight:600 }
.item .meta{ color:#667 }
.edit-hint{ margin-top:6px; color:#99a; font-size:12px }
</style>
